package services

import (
	"backend/models"

	"gorm.io/gorm"
)

type GroupService struct {
	db *gorm.DB
}

func NewGroupService(db *gorm.DB) *GroupService {
	return &GroupService{db: db}
}

func (g *GroupService) Create(m *models.Group) error {
	return g.db.Create(m).Error
}

func (g *GroupService) Update(id uint64, m *models.Group) error {
	return g.db.Where("id = ?", id).Updates(m).Error
}

func (g *GroupService) Delete(id uint64) error {
	return g.db.Where("id=?", id).Delete(&models.Group{}).Error
}

func (g *GroupService) GetList(q *models.PageInfo, m *models.Group) ([]*models.Group, int64, error) {
	var total int64
	var groups []*models.Group
	query := g.db.Model(&models.Group{})
	if m.Name != "" {
		query = query.Where("name = ?", m.Name)
	}
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}
	if err := query.Order("created_at DESC").Limit(q.Size).Offset((q.Page - 1) * q.Size).Find(&groups).Error; err != nil {
		return nil, 0, err
	}
	return groups, total, nil
}

func (g *GroupService) BindUser(group_id uint, user_ids []uint, action string) error {
	var group models.Group
	var users []models.User
	if err := g.db.First(&group, group_id).Error; err != nil {
		return err
	}
	if err := g.db.Find(&users, user_ids).Error; err != nil {
		return err
	}
	if action == "bind" {
		if err := g.db.Model(&group).Association("Users").Append(&users); err != nil {
			return err
		}
	} else if action == "ubind" {
		if err := g.db.Model(&group).Association("Users").Delete(&users); err != nil {
			return err
		}
	}

	return nil
}

func (g *GroupService) BindRole(group_id uint, role_ids []uint, action string) error {
	var group models.Group
	var roles []models.Role
	if err := g.db.First(&group, group_id).Error; err != nil {
		return err
	}
	if err := g.db.Find(&roles, role_ids).Error; err != nil {
		return err
	}
	if action == "bind" {
		if err := g.db.Model(&group).Association("Roles").Append(&roles); err != nil {
			return err
		}
	} else if action == "ubind" {
		if err := g.db.Model(&group).Association("Roles").Delete(&roles); err != nil {
			return err
		}
	}

	return nil
}

func (g *GroupService) ListBindUser(groupID uint, p *models.PageInfo, m *models.User) ([]*models.User, int64, error) {
	var group models.Group
	var total int64
	var users []*models.User

	// 先查询 group_id 对应的用户组
	if err := g.db.First(&group, groupID).Error; err != nil {
		return nil, 0, err
	}

	// 基于关联的 Users 构建查询
	query := g.db.Model(&models.User{}).Joins("JOIN user_groups ON user_groups.user_id = users.id").
		Where("user_groups.group_id = ?", groupID)

	// 过滤条件
	if m.Username != "" {
		query = query.Where("users.username LIKE ?", "%"+m.Username+"%")
	}
	if m.Email != "" {
		query = query.Where("users.email LIKE ?", "%"+m.Email+"%")
	}

	// 获取总记录数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	if err := query.Order("users.created_at DESC").Limit(p.Size).Offset((p.Page - 1) * p.Size).Find(&users).Error; err != nil {
		return nil, 0, err
	}

	return users, total, nil
}

func (g *GroupService) ListBindRole(groupID uint, p *models.PageInfo, m *models.Role) ([]*models.Role, int64, error) {
	var group models.Group
	var total int64
	var roles []*models.Role

	// 先查询 group_id 对应的用户组
	if err := g.db.First(&group, groupID).Error; err != nil {
		return nil, 0, err
	}

	// 基于关联的 Users 构建查询
	query := g.db.Model(&models.Role{}).Joins("JOIN group_roles ON group_roles.role_id = roles.id").
		Where("group_roles.group_id = ?", groupID)

	// 过滤条件
	if m.Name != "" {
		query = query.Where("roles.name LIKE ?", "%"+m.Name+"%")
	}

	// 获取总记录数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	if err := query.Order("roles.created_at DESC").Limit(p.Size).Offset((p.Page - 1) * p.Size).Find(&roles).Error; err != nil {
		return nil, 0, err
	}

	return roles, total, nil
}
